package edu.cdnu.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.io.FileUtils;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import edu.cdnu.common.constant.MessageConstatnt;
import edu.cdnu.common.dto.UploadStudentDto;
import edu.cdnu.common.result.ResultEntity;
import edu.cdnu.config.FileUploadConfiguration;
import edu.cdnu.pojo.StudentPojo;
import edu.cdnu.pojo.TeacherPojo;
import edu.cdnu.service.FileService;
import edu.cdnu.service.StudentService;
import edu.cdnu.service.TeacherService;
import edu.cdnu.utils.EncoderUtils;

/**
 * 关于文件操作的接口
 * @author ASUS AsingZ
 */
@RestController
@RequestMapping("/file")
public class FileController {
	
	@Autowired
	private FileService fileService;
	@Autowired
	private FileUploadConfiguration fileUploadConfiguration;
	@Autowired
	private StudentService studentService;
	@Autowired
	private TeacherService teacherService;
	
	/**
	 * 下载文件
	 * @param path
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/download")
	public ResponseEntity<byte[]> fileDownload(String path,HttpServletRequest request) throws Exception {
		// 创建该文件对象
		File file = new File(path);
		// 对文件名编码，防止中文文件乱码
		path = EncoderUtils.getFilename(request, path);
		// 设置响应头
		HttpHeaders headers = new HttpHeaders();
		// 通知浏览器以下载的方式打开文件
		headers.setContentDispositionFormData("attachment", path);
		// 定义以流的形式下载返回文件数据
		headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
		// 使用Sring MVC框架的ResponseEntity对象封装返回下载数据
		return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers,HttpStatus.OK);
	}
	
	
	/**
	 * 返回资源目录
	 * @return
	 */
	@GetMapping("/catalogue")
	public ResultEntity<?> getCatalogue() {
		return ResultEntity.createSuccessResult(fileService.selectCatalogueDtoHaveChildren());
	}
	
	/**
	 * 获取指定资源目录下资源列表
	 * @param catalogueId
	 * @return
	 */
	
	@GetMapping("/resourceList/{catalogueId}")
	public ResultEntity<?> getResourceList(@PathVariable Integer catalogueId){
		return ResultEntity.createSuccessResult(fileService.selectResourcePojoListByCatalogueId(catalogueId));
	}
	
	/**
	 * 上传资源
	 * @param catalogueId
	 * @param file
	 * @return
	 * @throws IOException 
	 */
	@RequestMapping("/upload/{catalogueId}")
	public ResultEntity<?> uploadFile(@PathVariable Integer catalogueId, @RequestParam("file") MultipartFile file) throws IOException{
		if(catalogueId==-1) {
			return ResultEntity.createFailResult(MessageConstatnt.DO_IT_FAIL);
		}
		//读取配置的路径,没有配置则设置默认路径
		String path=fileUploadConfiguration.getUploadPath();
		if(path == null) {
			path="f:/upload";
		}//判断 是否 以/结尾，是则去掉
		else if("/".equals(path.substring(path.length()-1))){
			//去掉末尾的/
			path = path.substring(0,path.length() -1);
		}
		InputStream in= file.getInputStream();
		//获取上传的文件名  这里是全名，有后缀的
		String fileName=file.getOriginalFilename();
		
		//时间戳(文件名)
		Long time = System.currentTimeMillis();
		
		//这里是创建文件夹
		File f=new File(path+"/"+time);
		if(!f.exists()) {
			f.mkdirs();
		}
		
		//全rurl
        String url=path+"/"+time+"/"+fileName;
        
		//写文件
		OutputStream out=new FileOutputStream(url);
		byte[] bs=new byte[1024];
		int len=-1;
		while((len=in.read(bs))!=-1) {
			out.write(bs,0,len);
		}
		in.close();
		out.close();
		
		// 数据库增加记录
		fileService.insertResource(fileName, url, catalogueId);
		
		return ResultEntity.createSuccessResult(null);
	}
	
	@GetMapping("/deleteResource/{resourceId}")
	public ResultEntity<?> deleteResource(@PathVariable Integer resourceId){
		fileService.deleteResource(resourceId);
		return ResultEntity.createSuccessResult(null);
	}
	
	/**
	 * 新增一个目录
	 * 现在使用{@link CatalogueController#addOrUpdateCatalogue}
	 * @param catalogueText
	 * @param parentId
	 * @return
	 */
	@GetMapping("/addCatalogue/{parentId}")
	@Deprecated
	public ResultEntity<?> addCatalogue(String catalogueText,@PathVariable Integer parentId){
		fileService.insertCatalogue(catalogueText, parentId);
		return ResultEntity.createSuccessResult(null);
	}
	
	/**
	 * 删除一个目录
	 * @param catalogueId
	 * @return
	 */
	@GetMapping("/deleteCatalogue/{catalogueId}")
	public ResultEntity<?> deleteCatalogue(@PathVariable Integer catalogueId){
		fileService.deleteCatalogue(catalogueId);
		return ResultEntity.createSuccessResult(null);
	}
	
	
	/**
	 * 批量导入学生
	 * 这里只能导入学生，过时了,建议使用{@link FileController#importUser}
	 * @param file
	 * @return
	 * @throws IOException
	 */
	@Deprecated
	@RequestMapping("/studentUpload")
	public ResultEntity<?> Upload(@RequestParam("studentFile") MultipartFile file) throws IOException {
		//读取配置的路径,没有配置则设置默认路径
		String path=fileUploadConfiguration.getUploadPath();
		if(path == null) {
			path="f:/upload";
		}//判断 是否 以/结尾，是则去掉
		else if("/".equals(path.substring(path.length()-1))){
			//去掉末尾的/
			path = path.substring(0,path.length() -1);
		}
		
		InputStream in= file.getInputStream();
		//获取上传的文件名
		String fileName=file.getOriginalFilename();
		
		//获取文件后缀名
		String suffix=file.getOriginalFilename().substring(fileName.lastIndexOf(".") + 1);
		//判断文件后缀不为xlsx或者xls;则直接return 
		if(!"xlsx".equals(suffix) && !"xls".equals(suffix) ) {
			return ResultEntity.createFailResult(MessageConstatnt.DO_IT_FAIL);
		}
		
		//时间戳(文件名)
		Long time = System.currentTimeMillis();
		
		//获取当前日期(文件目录)
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
        String currentDate =   dateFormat.format( new Date() );
        
        //这里是创建文件夹
		File f=new File(path+"/"+currentDate);
		if(!f.exists()) {
			f.mkdirs();
		}
		
		//全rurl
        String url=path+"/"+currentDate+"/"+time+"."+suffix;
        
		//写文件
		OutputStream out=new FileOutputStream(url);
		byte[] bs=new byte[1024];
		int len=-1;
		while((len=in.read(bs))!=-1) {
			out.write(bs,0,len);
		}
		in.close();
		out.close();
		
		
		FileInputStream inp = new FileInputStream(url);
		XSSFWorkbook wb = new XSSFWorkbook(inp); 
        XSSFSheet sheet = wb.getSheetAt(0); // Sheet1
		
        List<UploadStudentDto> list=new ArrayList<>();
        
        //读出每一行的数据
        for (Row row : sheet) {
        	/**
        	 * 第一列:角色
        	 */
        	String roleId;
        	//判断是否为空
        	if(row.getCell(0) != null && row.getCell(0).getCellType() !=CellType.BLANK) {
        		//判断单元格类型
        		if(row.getCell(0).getCellType() == CellType.NUMERIC) {
        			//数字类型转为String
        			roleId=String.valueOf(((int)row.getCell(0).getNumericCellValue()));
            	}else {
            		//其他类型直接读
            		roleId=row.getCell(0).getStringCellValue();
            	}
        		//标题去掉
        		if("角色".equals(roleId)) {
        			continue;
        		}
        	}else {
        		//为空下一列
        		continue;
        	}
        	/**
        	 * 第二列:账号
        	 */
        	String account;
        	//判断是否为空
        	if(row.getCell(1) != null && row.getCell(1).getCellType() !=CellType.BLANK) {
        		//不空直接取
        		account=row.getCell(1).getStringCellValue();
        		//标题去掉
        		if("账号".equals(account)) {
        			continue;
        		}
        	}else {
        		//为空下一列
        		continue;
        	}
        	
        	/**
        	 * 第三列:姓名
        	 */
        	String name;
        	//判断是否为空
        	if(row.getCell(1) != null && row.getCell(2).getCellType() !=CellType.BLANK) {
        		//不空直接取
        		name=row.getCell(2).getStringCellValue();
        		//标题去掉
        		if("姓名".equals(account)) {
        			continue;
        		}
        	}else {
        		//为空下一列
        		continue;
        	}
        	
        	/**
        	 * 第四列:院系
        	 */
        	String department=null;
        	//判断是否为空
        	if(row.getCell(3) != null && row.getCell(3).getCellType() !=CellType.BLANK) {
        		//判断单元格类型
        		if(row.getCell(3).getCellType() == CellType.NUMERIC) {
        			//数字类型转为String
        			department=String.valueOf(((int)row.getCell(3).getNumericCellValue()));
            	}else {
            		//其他类型直接读
            		department=row.getCell(3).getStringCellValue();
            	}
        	}
        	
        	/**
        	 * 第五列:专业
        	 */
        	String subject=null;
        	//判断是否为空
        	if(row.getCell(4) != null && row.getCell(4).getCellType() !=CellType.BLANK) {
        		//判断单元格类型
        		if(row.getCell(4).getCellType() == CellType.NUMERIC) {
        			//数字类型转为String
        			subject=String.valueOf(((int)row.getCell(4).getNumericCellValue()));
            	}else {
            		//其他类型直接读
            		subject=row.getCell(4).getStringCellValue();
            	}
        	}
        	
        	/**
        	 * 第六列:班级
        	 */
        	String clazz=null;
        	//判断是否为空
        	if(row.getCell(5) != null && row.getCell(5).getCellType() !=CellType.BLANK) {
        		//判断单元格类型
        		if(row.getCell(5).getCellType() == CellType.NUMERIC) {
        			//数字类型转为String
        			clazz=String.valueOf(((int)row.getCell(5).getNumericCellValue()));
            	}else {
            		//其他类型直接读
            		clazz=row.getCell(5).getStringCellValue();
            	}
        	}
        	
        	UploadStudentDto student=new UploadStudentDto(roleId,account,name,department,subject,clazz);
        	
        	list.add(student);
        	
        }
        wb.close();
        inp.close();
        
		//删除文件
//		File fileDel = new File(url);
//		fileDel.delete();
		
		return ResultEntity.createSuccessResult(list);
	}
	
	/**
	 * 下载导入用户示例
	 * @param request
	 * @return
	 * @throws Exception
	 */
	@GetMapping("/importExample")
	public ResponseEntity<byte[]> fileDownloadUserImportExample(HttpServletRequest request) throws Exception {
		String path = "F:\\education\\导入用户例子.xlsx";
		// 创建该文件对象
		File file = new File(path);
		// 对文件名编码，防止中文文件乱码
		path = EncoderUtils.getFilename(request, path);
		// 设置响应头
		HttpHeaders headers = new HttpHeaders();
		// 通知浏览器以下载的方式打开文件
		headers.setContentDispositionFormData("attachment", path);
		// 定义以流的形式下载返回文件数据
		headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
		// 使用Sring MVC框架的ResponseEntity对象封装返回下载数据
		return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers,HttpStatus.OK);
	}
	
	/**
	 * 批量导入用户
	 * @param file
	 * @return
	 * @throws IOException
	 */
	@RequestMapping("/importUser")
	public ResultEntity<?> importUser(@RequestParam("importUserFile") MultipartFile file) throws IOException{
		InputStream in= file.getInputStream();
		//获取上传的文件名
		String fileName=file.getOriginalFilename();
		//获取文件后缀名
		String suffix=file.getOriginalFilename().substring(fileName.lastIndexOf(".") + 1);
		//判断文件后缀不为xlsx或者xls;则直接return 
		if(!"xlsx".equals(suffix) && !"xls".equals(suffix) ) {
			return ResultEntity.createFailResult(MessageConstatnt.DO_IT_FAIL);
		}
		// 处理excel
		XSSFWorkbook wb = new XSSFWorkbook(in); 
        XSSFSheet sheet = wb.getSheetAt(0); // Sheet1
		// 保存每一行的数据
        List<Object> list=new ArrayList<>();
        
        //读出每一行的数据
        for (Row row : sheet) {
        	/**
        	 * 第一列:角色
        	 */
        	String role;
        	//判断是否为空
        	if(row.getCell(0) != null && row.getCell(0).getCellType() !=CellType.BLANK) {
        		//判断单元格类型
        		if(row.getCell(0).getCellType() == CellType.NUMERIC) {
        			//数字类型转为String
        			role=String.valueOf(((int)row.getCell(0).getNumericCellValue()));
            	}else {
            		//其他类型直接读
            		role=row.getCell(0).getStringCellValue();
            	}
        		//标题去掉
        		if("角色".equals(role)) {
        			continue;
        		}
        	}else {
        		//为空下一列
        		continue;
        	}
        	
        	/**
        	 * 第二列:账号
        	 */
        	String account=null;
        	//判断是否为空
        	if(row.getCell(1) != null && row.getCell(1).getCellType() !=CellType.BLANK) {
        		//判断单元格类型
        		if(row.getCell(1).getCellType() == CellType.NUMERIC) {
        			//数字类型转为String
        			account=String.valueOf(((int)row.getCell(1).getNumericCellValue()));
            	}else {
            		//其他类型直接读
            		account=row.getCell(1).getStringCellValue();
            	}
        		//标题去掉
        		if("账号".equals(account)) {
        			continue;
        		}
        	}else {
        		//为空下一列
        		continue;
        	}
        	
        	/**
        	 * 第三列:密码
        	 */
        	String password = null;
        	//判断是否为空
        	if(row.getCell(2) != null && row.getCell(2).getCellType() !=CellType.BLANK) {
        		//不空直接取
        		password=row.getCell(2).getStringCellValue();
        		//标题去掉
        		if("密码".equals(password)) {
        			continue;
        		}
        	}
        	
        	/**
        	 * 第四列:姓名
        	 */
        	String name=null;
        	//判断是否为空
        	if(row.getCell(3) != null && row.getCell(3).getCellType() !=CellType.BLANK) {
        		//不空直接取
        		name=row.getCell(3).getStringCellValue();
        		//标题去掉
        		if("姓名".equals(name)) {
        			continue;
        		}
        	}else {
        		//为空下一列
        		continue;
        	}
        	
        	/**
        	 * 第五列:电话
        	 */
        	String phone=null;
        	//判断是否为空
        	if(row.getCell(4) != null && row.getCell(4).getCellType() !=CellType.BLANK) {
        		//判断单元格类型
        		if(row.getCell(4).getCellType() == CellType.NUMERIC) {
        			//数字类型转为String
        			phone=String.valueOf(((int)row.getCell(4).getNumericCellValue()));
            	}else {
            		//其他类型直接读
            		phone=row.getCell(4).getStringCellValue();
            	}
        		//标题去掉
        		if("电话".equals(phone)) {
        			continue;
        		}
        	}
        	
        	/**
        	 * 第六列:邮箱
        	 */
        	String email=null;
        	//判断是否为空
        	if(row.getCell(5) != null && row.getCell(5).getCellType() !=CellType.BLANK) {
        		//判断单元格类型
        		if(row.getCell(5).getCellType() == CellType.NUMERIC) {
        			//数字类型转为String
        			email=String.valueOf(((int)row.getCell(5).getNumericCellValue()));
            	}else {
            		//其他类型直接读
            		email=row.getCell(5).getStringCellValue();
            	}
        		//标题去掉
        		if("邮箱".equals(email)) {
        			continue;
        		}
        	}
        	
        	/**
        	 * 第七列:学院
        	 */
        	String department=null;
        	//判断是否为空
        	if(row.getCell(6) != null && row.getCell(6).getCellType() !=CellType.BLANK) {
        		//判断单元格类型
        		if(row.getCell(6).getCellType() == CellType.NUMERIC) {
        			//数字类型转为String
        			department=String.valueOf(((int)row.getCell(6).getNumericCellValue()));
            	}else {
            		//其他类型直接读
            		department=row.getCell(6).getStringCellValue();
            	}
        		//标题去掉
        		if("学院".equals(department)) {
        			continue;
        		}
        	}
        	
        	/**
        	 * 第八列:状态
        	 */
        	String state=null;
        	//判断是否为空
        	if(row.getCell(7) != null && row.getCell(7).getCellType() !=CellType.BLANK) {
        		//判断单元格类型
        		if(row.getCell(5).getCellType() == CellType.NUMERIC) {
        			//数字类型转为String
        			state=String.valueOf(((int)row.getCell(7).getNumericCellValue()));
            	}else {
            		//其他类型直接读
            		state=row.getCell(7).getStringCellValue();
            	}
        		//标题去掉
        		if("状态".equals(state)) {
        			continue;
        		}
        	}
        	
        	/**
        	 *  判断角色 只有学生才有后面这几个
        	 */
        	if("5".equals(role)) {
        		/**
            	 * 第九列:专业
            	 */
            	String subject=null;
            	//判断是否为空
            	if(row.getCell(8) != null && row.getCell(8).getCellType() !=CellType.BLANK) {
            		//判断单元格类型
            		if(row.getCell(8).getCellType() == CellType.NUMERIC) {
            			//数字类型转为String
            			subject=String.valueOf(((int)row.getCell(8).getNumericCellValue()));
                	}else {
                		//其他类型直接读
                		subject=row.getCell(8).getStringCellValue();
                	}
            		//标题去掉
            		if("专业OR职称".equals(subject)) {
            			continue;
            		}
            	}
            	
            	/**
            	 * 第十列:班级
            	 */
            	String clazz=null;
            	//判断是否为空
            	if(row.getCell(9) != null && row.getCell(9).getCellType() !=CellType.BLANK) {
            		//判断单元格类型
            		if(row.getCell(8).getCellType() == CellType.NUMERIC) {
            			//数字类型转为String
            			clazz=String.valueOf(((int)row.getCell(9).getNumericCellValue()));
                	}else {
                		//其他类型直接读
                		clazz=row.getCell(9).getStringCellValue();
                	}
            		//标题去掉
            		if("班级".equals(clazz)) {
            			continue;
            		}
            	}
            	
            	/**
            	 * 第十一列:身份证号
            	 */
            	String idcard=null;
            	//判断是否为空
            	if(row.getCell(10) != null && row.getCell(9).getCellType() !=CellType.BLANK) {
            		//判断单元格类型
            		if(row.getCell(10).getCellType() == CellType.NUMERIC) {
            			//数字类型转为String
            			idcard=String.valueOf(((int)row.getCell(10).getNumericCellValue()));
                	}else {
                		//其他类型直接读
                		idcard=row.getCell(10).getStringCellValue();
                	}
            		//标题去掉
            		if("身份证".equals(idcard)) {
            			continue;
            		}
            	}
            		
            	// 学生创建学生对象
            	StudentPojo studentPojo=new StudentPojo(Integer.valueOf(role), account, password, name, idcard, phone, email, 
            			clazz==null?null:Integer.valueOf(clazz), 
    					subject==null?null:Integer.valueOf(subject),
						department==null?null:Integer.valueOf(department), 
						state==null?null:Integer.valueOf(state));
            	list.add(studentPojo);
            	studentService.addStudent(studentPojo);
            	
        	}else {
        		/**
        		 * 老师第九列为职称
        		 */
        		String degree=null;
        		//判断是否为空
            	if(row.getCell(8) != null && row.getCell(8).getCellType() !=CellType.BLANK) {
            		//不空直接取
            		degree=row.getCell(8).getStringCellValue();
            		//标题去掉
            		if("专业OR职称".equals(department)) {
            			continue;
            		}
            	}
            	
        		// 教师创建教师对象
        		TeacherPojo teacherPojo=new TeacherPojo(Integer.valueOf(role), account, password, name, email, phone, degree, 
        				department==null?null:Integer.valueOf(department), 
						state==null?null:Integer.valueOf(state));
        		list.add(teacherPojo);
        		teacherService.addTeacher(teacherPojo);
        	}
        	
        }
        wb.close();
        
		return ResultEntity.createSuccessResult(list);
	}
}
